/**
 * This is the class that runs the Cellular Automaton simulation
 * 
 */
package framework.cellularAutomaton;

import javax.swing.JFrame;

import framework.gui.panels.LifePanel;
import framework.interfaces.RuleSet;
import framework.interfaces.Visualization;
import framework.world.World;


/**
 * This class builds and runs the simulation
 * It initializes the framework.world of the automaton, and then builds the GUI
 */

public class CellularAutomaton {

	//Create object references to be "filled in" by the plugins
	private RuleSet rules;
	private Visualization visualizer;
	
	//Create the framework.world that will contain and run the Cellular Automaton
	private World world;
	
	//The main JFrame for the GUI window
	private JFrame controllerFrame;
	
	/**
	 * Create a new CellularAutomaton Simulation
	 * @param newRules The rules the simulation should follow
	 * @param newVisualizer The visualizer used to display it
	 */
	public CellularAutomaton(RuleSet newRules, Visualization newVisualizer){
		addRuleSetPlugin(newRules);
		addVisualizationPlugin(newVisualizer);
	}
	
	/**
	 * Initializes and displays the GUI
	 * @param theWorld the World that should be displayed
	 */
	private void createAndShowGUI(World theWorld){
		controllerFrame = new JFrame("Digital Life");
		controllerFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		LifePanel ui = new LifePanel(this);
		
		ui.setOpaque(true);
		
		controllerFrame.add(ui);	
		controllerFrame.setContentPane(ui);
		controllerFrame.pack();
		controllerFrame.setLocationRelativeTo(null);
		controllerFrame.setVisible(true);
	}
	
	public JFrame getControllerFrame(){
		return controllerFrame;
	}
	
	/**
	 * Get the framework.world being used in the simulation
	 * @return the framework.world being used in the simulation
	 */
	public World getWorld(){
		return world;
	}
	
	/**
	 * Adds a RuleSet plugin to the simulation
	 * @param newRules the RuleSet plugin to use
	 */
	public void addRuleSetPlugin(RuleSet newRules){
		rules = newRules;
	}
	
	/**
	 * Adds a Visualization plugin to the simulation
	 * @param newVisualizer the Visualization plugin to use
	 */
	public void addVisualizationPlugin(Visualization newVisualizer){
		visualizer = newVisualizer;
	}
	
	/**
	 * Start the framework.world and simulation
	 */
	public void start(){
		world = new World(rules, visualizer);
		
		createAndShowGUI(world);
	}
}
